<template>
  <div flex="~ col">
    <!-- 查询表单区域 -->
    <div>
      <el-form :inline="true" :model="queryForm">
        <el-form-item label="权限名称">
          <el-input v-model="queryForm.permName" placeholder="请输入权限名称" clearable />
        </el-form-item>
        <el-form-item label="权限类型">
          <el-select v-model="queryForm.permType" placeholder="请选择权限类型" clearable>
            <el-option label="菜单" :value="1" />
            <el-option label="按钮" :value="2" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 操作按钮区域 -->
    <div class="mb-4 flex justify-between items-center">
      <div class="flex items-center gap-2">
        <el-button @click="toggleAllExpand(true)">展开全部</el-button>
        <el-button @click="toggleAllExpand(false)">收起全部</el-button>
        <el-button @click="refreshData" :loading="tableLoading">刷新数据</el-button>
      </div>
      <el-button type="primary" @click="handleAdd">新增权限</el-button>
    </div>

    <!-- 树形表格 -->
    <div class="table-container">
      <el-table
        height="600px"
        ref="tableRef"
        :data="treeData"
        border
        style="width: 100%"
        v-loading="tableLoading"
        row-key="id"
        :tree-props="{ children: 'children' }"
        :default-expand-all="defaultExpandAll"
        :max-height="600"
        :scrollbar-always-on="true"
        @expand-change="handleExpandChange"
      >
        <el-table-column prop="permName" label="权限名称" width="200" show-overflow-tooltip>
          <template #default="{ row }">
            <div class="flex items-center gap-2">
              <i v-if="row.icon && row.permType === 1" :class="row.icon" class="text-blue-500" />
              <span>{{ row.permName }}</span>
              <el-tag v-if="row.children && row.children.length > 0" size="small" type="info">
                {{ row.children.length }}
              </el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="permCode" label="权限编码" width="180" show-overflow-tooltip />
        <el-table-column prop="permType" label="权限类型" width="100">
          <template #default="{ row }">
            <el-tag :type="row.permType === 1 ? 'primary' : 'success'" size="small">
              {{ row.permType === 1 ? '菜单' : '按钮' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="描述" min-width="150" show-overflow-tooltip />
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="{ row }">
            <el-button link type="success" size="small" @click="handleAddChild(row)"
              >添加子权限</el-button
            >
            <el-button link type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
            <el-button link type="danger" size="small" @click="handleDelete(row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 新增/编辑权限对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="700px"
      destroy-on-close
      @close="handleDialogClose"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="权限名称" prop="permName">
              <el-input v-model="form.permName" placeholder="请输入权限名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="权限类型" prop="permType">
              <el-select v-model="form.permType" placeholder="请选择权限类型" style="width: 100%">
                <el-option label="菜单" :value="1" />
                <el-option label="按钮" :value="2" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="权限编码" prop="permCode">
              <el-input v-model="form.permCode" placeholder="自动生成或手动输入">
                <template #append>
                  <el-button @click="generatePermCode">自动生成</el-button>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="!isTopLevel">
            <el-form-item label="父权限" prop="parentId">
              <el-tree-select
                v-model="form.parentId"
                :data="parentOptions"
                :props="{ label: 'permName', value: 'id', children: 'children' }"
                placeholder="请选择父权限"
                style="width: 100%"
                check-strictly
                :render-after-expand="false"
              />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="描述" prop="description">
          <el-input
            v-model="form.description"
            type="textarea"
            :rows="2"
            placeholder="请输入权限描述"
          />
        </el-form-item>

        <!-- 菜单类型特有字段 -->
        <template v-if="form.permType === 1">
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="路由路径" prop="path">
                <el-input v-model="form.path" placeholder="如：/user" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="组件路径" prop="component">
                <el-input v-model="form.component" placeholder="如：user/index" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-form-item label="菜单图标" prop="icon">
            <el-input v-model="form.icon" placeholder="如：el-icon-user">
              <template #prefix>
                <i v-if="form.icon" :class="form.icon" />
              </template>
            </el-input>
          </el-form-item>
        </template>

        <!-- 权限编码提示 -->
        <el-alert :title="permCodeTip" type="info" :closable="false" show-icon class="mb-4" />
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, computed, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance } from 'element-plus'
import {
  fetchList,
  createPermission,
  updatePermission,
  deletePermissionr,
  getPermissionByUser
} from '@/api/permission'
import { useUserStore } from '../../../store/user'

// 类型定义
interface PermissionItem {
  id?: number
  permName: string
  permCode: string
  permType: number
  parentId: number | null
  description: string
  path?: string
  component?: string
  icon?: string
  createTime?: string
  updateTime?: string
  children?: PermissionItem[]
}

// 常量定义
const PERMISSION_TYPE = {
  MENU: 1,
  BUTTON: 2
} as const

// 状态管理
const userStore = useUserStore()

// 表格相关
const tableRef = ref()
const tableData = ref<PermissionItem[]>([])
const treeData = ref<PermissionItem[]>([])
const tableLoading = ref(false)
const defaultExpandAll = ref(true)
const expandedKeys = ref<Set<number>>(new Set())

// 对话框相关
const dialogVisible = ref(false)
const dialogType = ref<'add' | 'edit' | 'addChild'>('add')
const submitLoading = ref(false)
const formRef = ref<FormInstance>()
const parentRow = ref<PermissionItem | null>(null)

// 查询表单
const queryForm = ref({
  permName: '',
  permType: undefined as number | undefined,
  limit: 999,
  page: 1
})

// 表单数据
const defaultForm: PermissionItem = {
  permName: '',
  permCode: '',
  permType: PERMISSION_TYPE.MENU,
  parentId: null,
  description: '',
  path: '',
  component: '',
  icon: ''
}

const form = ref<PermissionItem>({ ...defaultForm })

// 计算属性
const isTopLevel = computed(() => dialogType.value === 'add')
const parentOptions = computed(() => buildTreeOptions(treeData.value))
const dialogTitle = computed(() => {
  switch (dialogType.value) {
    case 'add':
      return '新增顶级权限'
    case 'addChild':
      return `为 "${parentRow.value?.permName}" 添加子权限`
    case 'edit':
      return '编辑权限'
    default:
      return '权限管理'
  }
})

const permCodeTip = computed(() => {
  if (form.value.permType === PERMISSION_TYPE.MENU) {
    const parentInfo = parentRow.value
      ? `继承父级前缀"${parentRow.value.permCode?.split(':')[0] || 'page'}"`
      : ''
    return `菜单权限编码格式：前缀:页面标识，如：page:user、system:role。${parentInfo}权限名称包含中文时请手动输入编码。`
  } else {
    const parentInfo = parentRow.value
      ? `继承父级前缀"${parentRow.value.permCode?.split(':')[0] || 'system'}"`
      : ''
    return `按钮权限编码格式：前缀:操作，如：user:read、user:create、user:update、user:delete。${parentInfo}权限名称包含中文时请手动输入编码。`
  }
})

// 表单验证规则
const rules = {
  permName: [{ required: true, message: '请输入权限名称', trigger: 'blur' }],
  permCode: [{ required: true, message: '请输入权限编码', trigger: 'blur' }],
  permType: [{ required: true, message: '请选择权限类型', trigger: 'change' }],
  description: [{ required: true, message: '请输入权限描述', trigger: 'blur' }]
}

/**
 * 构建树形选项
 */
const buildTreeOptions = (data: PermissionItem[]): PermissionItem[] => {
  return data
    .filter((item) => item.permType === PERMISSION_TYPE.MENU)
    .map((item) => ({
      ...item,
      children: item.children ? buildTreeOptions(item.children) : []
    }))
}

/**
 * 构建树形结构 - 优化版本
 */
const buildTree = (data: PermissionItem[]): PermissionItem[] => {
  if (!data || data.length === 0) return []

  const map = new Map<number, PermissionItem>()
  const roots: PermissionItem[] = []

  // 第一遍：创建所有节点的映射
  data.forEach((item) => {
    if (item.id) {
      map.set(item.id, {
        ...item,
        children: []
      })
    }
  })

  // 第二遍：构建父子关系
  data.forEach((item) => {
    if (!item.id) return

    const node = map.get(item.id)
    if (!node) return

    const parentId = normalizeParentId(item.parentId)
    if (!parentId) {
      // 根节点
      roots.push(node)
    } else {
      const parent = map.get(parentId)
      if (parent) {
        parent.children!.push(node)
      } else {
        // 找不到父节点，作为根节点处理
        console.warn(`找不到父节点 ${parentId}，将节点 ${item.id} 作为根节点处理`)
        roots.push(node)
      }
    }
  })

  // 递归排序所有层级的节点
  const sortTree = (nodes: PermissionItem[]) => {
    nodes.sort((a, b) => {
      // 先按权限类型排序（菜单在前，按钮在后）
      if (a.permType !== b.permType) {
        return a.permType - b.permType
      }
      // 再按权限名称排序
      return a.permName.localeCompare(b.permName)
    })

    nodes.forEach((node) => {
      if (node.children && node.children.length > 0) {
        sortTree(node.children)
      }
    })
  }

  sortTree(roots)
  return roots
}

/**
 * 标准化父ID格式
 */
const normalizeParentId = (parentId: number | null | undefined): number | null => {
  if (parentId === null || parentId === 0 || parentId === undefined) {
    return null
  }
  return typeof parentId === 'string' ? parseInt(parentId, 10) : parentId
}

/**
 * 获取权限列表数据 - 优化版本
 */
const getList = async (preserveExpandState = false) => {
  try {
    tableLoading.value = true

    // 保存当前展开状态
    const currentExpandedKeys = preserveExpandState ? new Set(expandedKeys.value) : new Set()

    const params = {
      permName: queryForm.value.permName,
      permType: queryForm.value.permType,
      limit: 999,
      page: 1
    }

    const res = await fetchList(params)
    const list = res.data?.list || res.data || []

    if (!Array.isArray(list)) {
      console.error('API返回的数据格式不正确:', res)
      ElMessage.error('数据格式错误')
      return
    }

    tableData.value = list
    treeData.value = buildTree(list)

    // 恢复展开状态
    if (preserveExpandState && currentExpandedKeys.size > 0) {
      nextTick(() => {
        restoreExpandState(currentExpandedKeys)
      })
    }
  } catch (error) {
    console.error('获取权限列表失败:', error)
    ElMessage.error('获取权限列表失败')
  } finally {
    tableLoading.value = false
  }
}

/**
 * 恢复展开状态
 */
const restoreExpandState = (expandedKeys: Set<number>) => {
  const restoreExpansion = (data: PermissionItem[]) => {
    data.forEach((item) => {
      if (item.id && expandedKeys.has(item.id)) {
        tableRef.value?.toggleRowExpansion(item, true)
      }
      if (item.children && item.children.length > 0) {
        restoreExpansion(item.children)
      }
    })
  }
  restoreExpansion(treeData.value)
}

/**
 * 处理展开状态变化
 */
const handleExpandChange = (row: PermissionItem, expanded: boolean) => {
  if (row.id) {
    if (expanded) {
      expandedKeys.value.add(row.id)
    } else {
      expandedKeys.value.delete(row.id)
    }
  }
}

/**
 * 展开/收起全部节点 - 优化版本
 */
const toggleAllExpand = (expand: boolean) => {
  nextTick(() => {
    expandedKeys.value.clear()

    const toggleRows = (data: PermissionItem[]) => {
      data.forEach((item) => {
        // const hasChildren = item.hasChildren || (item.children && item.children.length > 0)
        if (item.id) {
          tableRef.value?.toggleRowExpansion(item, expand)
          if (expand) {
            expandedKeys.value.add(item.id)
          }
          if (item.children) {
            toggleRows(item.children)
          }
        }
      })
    }
    toggleRows(treeData.value)
  })
}

/**
 * 刷新数据
 */
const refreshData = () => {
  getList(true)
}

/**
 * 处理查询操作
 */
const handleQuery = () => {
  getList()
}

/**
 * 重置查询表单
 */
const resetQuery = () => {
  queryForm.value = {
    permName: '',
    permType: undefined,
    limit: 999,
    page: 1
  }
  getList()
}

/**
 * 处理新增权限
 */
const handleAdd = () => {
  resetForm()
  dialogType.value = 'add'
  dialogVisible.value = true
}

/**
 * 处理添加子权限
 */
const handleAddChild = (row: PermissionItem) => {
  resetForm()
  form.value = {
    ...defaultForm,
    parentId: row.id!,
    permType: row.permType === PERMISSION_TYPE.MENU ? PERMISSION_TYPE.BUTTON : PERMISSION_TYPE.MENU
  }
  dialogType.value = 'addChild'
  parentRow.value = row
  dialogVisible.value = true
}

/**
 * 重置表单数据
 */
const resetForm = () => {
  form.value = { ...defaultForm }
  parentRow.value = null
  if (formRef.value) {
    formRef.value.resetFields()
  }
}

/**
 * 生成权限编码
 */
const generatePermCode = () => {
  const { permName, permType, parentId } = form.value

  // if (!permName) {
  //   ElMessage.warning('请先输入权限名称')
  //   return
  // }

  let code = ''
  let prefix = ''

  // 获取父级权限的前缀

  if (parentRow.value?.permCode) {
    prefix = getPrefixFromCode(parentRow.value.permCode)
  } else if (parentId) {
    const parent = findParentNode(treeData.value, parentId)
    prefix = parent?.permCode ? getPrefixFromCode(parent.permCode) : ''
  }

  if (permType === PERMISSION_TYPE.MENU) {
    // 菜单权限格式：父级前缀:页面标识 或 page:页面标识
    const pageId = formatCodeSegment(permName)
    code = prefix && prefix !== 'page' ? `${prefix}:${pageId}` : `page:${pageId}`
  } else {
    // 按钮权限格式：父级前缀:操作 或 system:操作
    const action = formatCodeSegment(permName)
    code = prefix ? `${prefix}:${action}` : `system:${action}`
  }

  form.value.permCode = code
}

/**
 * 从权限编码中提取前缀
 */
const getPrefixFromCode = (code: string): string => {
  return code.includes(':') ? code.split(':')[1] : code
}

/**
 * 格式化编码片段（转为小写并移除非字母数字字符）
 */
const formatCodeSegment = (name: string): string => {
  return name.toLowerCase().replace(/[^a-z0-9]/g, '')
}

/**
 * 在树形数据中查找父节点
 */
const findParentNode = (data: PermissionItem[], id: number): PermissionItem | null => {
  for (const item of data) {
    if (item.id === id) return item
    if (item.children) {
      const found = findParentNode(item.children, id)
      if (found) return found
    }
  }
  return null
}

/**
 * 处理编辑权限
 */
const handleEdit = (row: PermissionItem) => {
  resetForm()
  form.value = { ...row }
  dialogType.value = 'edit'

  if (row.parentId) {
    parentRow.value = findParentNode(treeData.value, row.parentId)
  } else {
    parentRow.value = null
  }

  dialogVisible.value = true
}

/**
 * 处理删除权限 - 优化版本
 */
const handleDelete = async (row: PermissionItem) => {
  if (!row.id) return

  // 检查是否有子权限
  if (row.children && row.children.length > 0) {
    ElMessage.warning('该权限下还有子权限，请先删除子权限')
    return
  }

  try {
    await ElMessageBox.confirm(`确定要删除权限"${row.permName}"吗？`, '删除确认', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    await deletePermissionr(row.id)
    ElMessage.success('删除成功')

    // 立即刷新数据，保持展开状态
    await getList(true)
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  }
}

/**
 * 对话框关闭处理
 */
const handleDialogClose = () => {
  resetForm()
}

/**
 * 提交表单 - 优化版本
 */
const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    const valid = await formRef.value.validate()
    if (!valid) return

    submitLoading.value = true

    // 处理提交数据
    const submitData = { ...form.value }

    // 按钮类型清空菜单特有字段
    if (submitData.permType === PERMISSION_TYPE.BUTTON) {
      submitData.path = ''
      submitData.component = ''
      submitData.icon = ''
    }

    // 顶级权限parentId设为null
    if (dialogType.value === 'add') {
      submitData.parentId = null
    }

    // 执行API请求
    if (dialogType.value === 'edit') {
      await updatePermission(submitData)
      ElMessage.success('更新成功')
    } else {
      await createPermission(submitData)
      ElMessage.success('添加成功')
    }

    dialogVisible.value = false

    // 立即刷新数据，保持展开状态
    await getList(true)
  } catch (error) {
    console.error('操作失败:', error)
    ElMessage.error(dialogType.value === 'edit' ? '更新失败' : '添加失败')
  } finally {
    submitLoading.value = false
  }
}

// 监听权限类型变化，清空相关字段
watch(
  () => form.value.permType,
  (newType) => {
    if (newType === PERMISSION_TYPE.BUTTON) {
      // 按钮类型，清空菜单特有字段
      form.value.path = ''
      form.value.component = ''
      form.value.icon = ''
    }
    // 只有在新增时才清空权限编码，编辑时保留原有编码
    if (dialogType.value !== 'edit') {
      form.value.permCode = ''
    }
  }
)

// 监听权限名称变化，自动生成编码
watch(
  () => form.value.permName,
  () => {
    if (form.value.permName && !form.value.permCode && dialogType.value !== 'edit') {
      generatePermCode()
    }
  }
)

// 组件挂载时获取数据
onMounted(() => {
  if (userStore.token) {
    getList()
  }
})

// 暴露给父组件的方法
defineExpose({
  getList,
  refreshData,
  treeData
})
</script>

<style lang="scss" scoped>
:deep(.el-form-item__content) {
  @apply w-64;
}

.el-tag {
  font-size: 12px;
}

.dialog-footer {
  @apply flex justify-end gap-2;
}

:deep(.el-table .el-table__row .el-table__cell) {
  padding: 8px 0;
}

:deep(.el-tree-select) {
  width: 100%;
}

.text-gray-400 {
  color: #9ca3af;
}

.text-blue-500 {
  color: #3b82f6;
}

/* 表格容器样式 */
.table-container {
  border: 1px solid #ffffff;
  border-radius: 4px;
  overflow: hidden;
}

/* 表格滚动条样式优化 */
:deep(.el-table__body-wrapper) {
  /* 自定义滚动条样式 */
  &::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }

  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 4px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 4px;

    &:hover {
      background: #a8a3a8;
    }
  }
}

/* 确保表格有合适的最大高度和滚动 */
:deep(.el-table) {
  .el-table__header-wrapper,
  .el-table__body-wrapper {
    overflow-x: auto;
  }
}

/* 权限数量标签样式 */
.el-tag {
  margin-left: 4px;
  font-size: 10px;
  height: 16px;
  line-height: 14px;
  padding: 0 4px;
}
</style>
